<template>
    <div class="part-fr form-part">
        <el-row class="content" :gutter="20">
            <el-col class="left col-fr" :span="5">
                <div class="component-fr component-box">
                    <div class="component-list" v-for="item in letfFormData" :key="item.id">
                        <div class="box-title">{{ item.name }}</div>
                        <div class="dash-line"></div>
                        <draggable :class="['select-component flex', item.type]" v-model="item.children" :group="{ name: item.type === 'layout' ? 'rowForm' : 'colForm', pull: 'clone', put: false }" :clone="cloneItem" @end="moveEnd" :move="moveEvent" :sort="false" item-key="type">
                            <template #item="{ element }">
                                <div class="item move-status">{{ element.name }}</div>
                            </template>
                        </draggable>
                    </div>
                </div>
            </el-col>
            <el-col class="middle component-fr col-fr" :span="12">
                <!-- 行容器 -->
                <draggable class="show-component drag-padding" v-model="result" :group="{ name: 'row', pull: true, put: true }" item-key="uuid">
                    <template #item="one">
                        <RenderLayoutComponent v-if="one.element.componentTypeType === 'layout' || one.element.componentTypeType === 'fixed'" :class="['row-container container', { 'active': curRowIndex == one.index, 'fixed': one.element.componentTypeType === 'fixed' }]" :item="one.element" @changeItem="setPropsValue($event, one.element)" @click.stop="selectRow(one.element, one.index)">
                            <PageTool :item="result" :num="one.index" @removeItem="removeItem"></PageTool>
                            <!-- {{result}} -->
                            <draggable class="drag-padding row two el-row" v-model="one.element.children" :group="{ name: 'row', pull: true, put: true }" item-key="uuid">
                               <template #item="two">
                                   <RenderLayoutComponent v-if="two.element.componentTypeType === 'layout'" :class="['row-container container', { 'active': curRowIndex == `${one.index}-${two.index}`}]" :item="two.element" @changeItem="setPropsValue($event, two.element)" @click.stop="selectRow(two.element, `${one.index}-${two.index}`)">
                                       <!-- 工具栏 -->
                                       <PageTool :item="one.element.children" :num="two.index" @removeItem="removeItem"></PageTool>
                                       <draggable class="drag-padding three" v-model="two.element.children" :group="{ name: 'colForm', pull: true, put: true }" item-key="uuid">
                                           <template #item="three">
                                               <div :class="['container no-layout', { 'active': curRowIndex == `${one.index}-${two.index}-${three.index}`}]" @click.stop="selectRow(three.element, `${one.index}-${two.index}-${three.index}`)">
                                                   <!-- 工具栏 -->
                                                   <PageTool :item="two.element.children" :num="three.index" @removeItem="removeItem"></PageTool>
                                                   <!-- 内容 -->
                                                   <!-- <label for="">{{setAttr(three.element.attribute, 'showLabel', false)}}</label> -->
                                                  <RenderContainer :item="three.element"  v-show="showComponent(three.element)"></RenderContainer>
                                               </div>
                                           </template>
                                       </draggable>
                                   </RenderLayoutComponent>
                                   <div :class="['container no-layout', { 'active': curRowIndex == `${one.index}-${two.index}`}]" v-else @click.stop="selectRow(two.element, `${one.index}-${two.index}`)">
                                       <!-- 工具栏 -->
                                     <PageTool :item="one.element.children" :num="two.index" @removeItem="removeItem"></PageTool>
                                       <RenderContainer :item="two.element" v-show="showComponent(two.element)"></RenderContainer>
                                   </div>
                               </template>
                            </draggable>
                        </RenderLayoutComponent>
                        <div :class="['container no-layout', { 'active': curRowIndex == `${one.index}`}]" v-else>
                            <!-- 工具栏 -->
                            <PageTool :item="result" :num="one.index" @removeItem="removeItem"></PageTool>
                            <RenderContainer :item="one.element" @click.stop="selectRow(one.element, `${one.index}`)"></RenderContainer>
                        </div>
                    </template>
                </draggable>
            </el-col>
            <el-col class="right col-fr" :span="7">
				<!-- {{rightAttribute.attribute}} -->
                <div class="ctrl-btn">
                    <el-button type="primary" size="mini" @click="savePageDialog = true">保存</el-button>
                    <el-button type="primary" size="mini" @click="gotoPage">页面列表</el-button>
                    <el-button type="primary" size="mini" @click="gotoPrePage">预览</el-button>
                </div>
                <div class="component-fr scroll-y">
                    <Attriubte v-if="!!rightAttribute['attribute']" :list="rightAttribute.attribute"></Attriubte>
                </div>
            </el-col>
        </el-row>
        <el-dialog v-model="savePageDialog" title="保存页面" width="40%" center>
            <div class="page-info">
                <el-form :model="pageInfo" size="mini">
                    <el-form-item label="页面Mate:" :label-width="80">
                        <el-input v-model="pageInfo.mate" autocomplete="off" placeholder="请输入页面Mate:"/>
                    </el-form-item>
                    <el-form-item label="页面名称:" :label-width="80">
                        <el-input v-model="pageInfo.pageName" autocomplete="off" placeholder="请输入页面名称:"/>
                    </el-form-item>
                </el-form>
            </div>
            <template #footer>
              <span class="dialog-footer">
                <el-button @click="savePageDialog = false" size="mini">取消</el-button>
                <el-button type="primary" size="mini" @click="savePage();"
                  >确认</el-button
                >
              </span>
            </template>
          </el-dialog>
    </div>
</template>

<script>
import { ref, computed } from 'vue'
import { useStore } from 'vuex'
import componentConfig from 'static/json/componentConfig.json'
import draggable from 'vuedraggable'
import { ElMessage } from 'element-plus'
// import BasicComponent from '@/components/common/BasicComponent.vue'
import RenderContainer from '@/components/common/RenderContainer.vue'
import RenderLayoutComponent from '@/components/common/RenderLayoutComponent.vue'
import Attriubte from '@/components/common/Attribute.vue'
import PageTool from '@/components/common/PageTool/Index.vue'
import { basicComponent, basicPage } from '@/api/index.js'
import allowList from 'static/json/positionConfig.json'
import yunApi from 'static/js/toolApi.js'
// import componentConfig from 'static/json/componentConfig.json';
// import { init } from 'static/js/handlerComponentConfig.js';
export default {
    components: {
        draggable,
        // BasicComponent,
        Attriubte,
        PageTool,
        RenderContainer,
        RenderLayoutComponent
    },
    setup() {
        // init(componentConfig.list);
        // 定义变量
        const store = useStore(); // 使用useStore方法
        const userInfo = computed(() => store.state.userInfo);
        const loginStatus = computed(() => store.state.loginStatus);
        let curIndex = ref(-1) // 选中的下标
        let letfFormData = ref([]) // 左侧表单数据
        let result = ref([])
        let savePageDialog = ref(false) // 保存页面弹窗
        let addCurIndex = ref(-1) // 添加后的位置
        let rightAttribute = ref({}) // 当前右侧展示的属性
        let curRowIndex = ref(0) // 当前选中的行
        let numberVal = ref(['slider', 'number', 'gutter'])
        let flagString = ref(''); // 选中标记
        // 页面信息
        let pageInfo = ref({
            id: '',
            mate: '',
            pageName: ''
        })
        let showGlobalStatus = ref('')
        // 定义方法
        function moveEvent(evt, originalEvent) {
            // 移动成功才会赋值
            curIndex.value = evt.draggedContext.futureIndex
            let fromItem = evt.draggedContext
            let toItem = evt.relatedContext
            let toDom = evt.to
            // 判断当前位置合法性
            if (!judgeDrag(evt.to, fromItem, toItem, toDom)) {
                addCurIndex.value = fromItem.futureIndex
            } else {
                addCurIndex.value = -1
            }
        }
        
        function changeDarg(evt) {
        }
        // 判断是否拖拽合法
        function judgeDrag(evtTo, fromItem, toItem, toDom) {
            // 第一级
            if (evtTo.className.indexOf('show-component') > -1) {
                if (fromItem.element.componentTypeType !== 'layout' && fromItem.element.componentTypeType !== 'fixed') {
                    return false
                }
            }
            return true
        }
        // 计算唯一标识
        function calculateFlag(one, twe, three) {
            
        }
		function moveStart(evt) {
			console.log('开始时')
		}
        // 拖拽结束
        function endDrag(evt) {
            console.log('拖拽结束', evt)
        }
        // 移动结束
        function moveEnd(evt) {
            console.log('移动结束', result.value)
            if (evt.from.className === evt.to.className) {
                return
            }
            if (addCurIndex.value !== -1) {
                let containers = document.querySelectorAll('.show-component>.no-layout')
                containers.forEach(item => {
                    item.querySelector('.page-tool .close').click();
                })
                // console.log(containers[evt.newIndex].querySelector('.page-tool .close'))
                // containers[evt.newIndex].querySelector('.page-tool .close').click();
                // evt.to.querySelector('.page-tool .close').click();
                ElMessage({
                    message: '此处不允许添加该类组件，请选择合适的位置重新添加',
                    type: 'warning'
                })
            }
        }
        // 撤销非法拖拽
        function cancelCurDarg(fromItem, toItem) {
        }
        // 获取左侧组件列表
        function getLeftComponent() {
            let param = {
                pageNum: 1,
                pageSize: 100
            }
            basicComponent.getComponentList(param).then((res) => {
                if (res.status === 1) {
                    // 将返回来的组件分类
                    let temp = {}
                    res.data.list.map((item) => {
                        if (!temp[item.componentTypeType]) {
                            temp[item.componentTypeType] = {
                                id: item.componentType,
                                name: item.componentTypeName,
                                type: item.componentTypeType,
                                children: []
                            }
                        }
                        if (item.componentTypeType === 'layout' || item.componentTypeType === 'fixed') {
                            item.children = []
                        }
                        // if (item.attribute)
                        try {
                            item.attribute = JSON.parse(item.attribute)
                        } catch {
                            console.log('错误item', item.attribute)
                        }
                        for (let key in item.attribute) {
                            switch (item.attribute[key].type) {
                                case 'string':
                                    // item.attribute[key].value = (typeof item.attribute[key].value !== 'string') ? '' + item.attribute[key].value) : item.attribute[key].value
                                    break
                                case 'number':
                                    item.attribute[key].value = (typeof item.attribute[key].value !== 'number') ? parseFloat(item.attribute[key].value) : item.attribute[key].value
                                    break
                                case 'boolean':
                                    item.attribute[key].value = (typeof item.attribute[key].value !== 'boolean') ? item.attribute[key].value === 'true' : item.attribute[key].value
                                    break
                                case 'object':
                                    item.attribute[key].value = (typeof item.attribute[key].value !== 'object') ? JSON.parse(item.attribute[key].value) : item.attribute[key].value
                                    break
                            }
                        }
                        temp[item.componentTypeType].children.push(item)
                    })
                    letfFormData.value = temp
                }
            })
        }
        // 选择组件
        function selectItem(item) {
            // changeObjtoArr(item.attribute)
            for (let key in item.attribute) {
                item.attribute[key].tempStr = JSON.stringify(item.attribute[key].extendData)
            }
			rightAttribute.value = item
        }
        // 选择行
        function selectRow(item, index) {
            curRowIndex.value = index
			this.selectItem(item)
        }
        // 将对象转化成数组
        function changeObjtoArr(obj) {
            rightAttribute.value = []
            for (let key in obj) {
                // if (numberVal.value.indexOf(obj[key].type) > -1) {
                //     obj[key].value = parseInt(obj[key].value)
                // }
                rightAttribute.value.push(obj[key])
            }
        }
        // 监听值变化
        function change(e, item) {
            item.attribute.defaultValue.value = e
        }
        // 修改属性值
        function setPropsValue(e, item) {
            item.attribute[e.key].value = e.value
        }
        // 移除tempStr
        function removeTempStr(list) {
            list.map(item => {
                for (let key in item.attribute) {
                    delete item.attribute[key]['tempStr']
                }
                if (item.children && item.children.length > 0) {
                    removeTempStr(item.children)
                }
            })
        }
        // 保存页面
        function savePage() {
            removeTempStr(result.value)
            console.log('result.value', result.value)
            let params = {
                id: pageInfo.value.id ? pageInfo.value.id : '',
                mate: pageInfo.value.mate,
                pageName: pageInfo.value.pageName,
                author: userInfo.value.userId,
                pageInfo: JSON.stringify(result.value)
            }
            let func = null;
            if (params.id) {
                func = basicPage.putPage
            } else {
                func = basicPage.addPage
            }
            func(params).then(res => {
                if (res.status === 1) {
                    savePageDialog.value = false;
                    ElMessage({
                        message: '保存页面成功',
                        type: 'success'
                    })
                } else {
                    ElMessage({
                        message: '保存页面失败',
                        type: 'error'
                    })
                }
            })
        }
        // 获取页面信息
        function getPageInfo(id) {
            let params = {
                id: id,
                userId: userInfo.value.userId
            }
            basicPage.getPageInfoById(params).then(res => {
                if (res.status === 1) {
                    pageInfo.value.id = res.data.list.id
                    pageInfo.value.mate = res.data.list.mate
                    pageInfo.value.pageName = res.data.list.pageName
                    result.value = JSON.parse(res.data.list.pageInfo)
					console.log(result.value)
                } else {
                    ElMessage({
                        message: '获取页面失败',
                        type: 'error'
                    })
                }
            })
        }
        // 设置属性
        function setAttr(attribute, name, value = '') {
            return Object.prototype.hasOwnProperty.call(attribute, name) ? attribute[name].value : value
        }
        // 判断是否显示
        function showComponent(obj) {
            if (obj.attribute['vIfComponent'] && obj.attribute['vIfComponent'].value !== '') {
                let temp = JSON.parse(obj.attribute['vIfComponent'].value)
                return temp.event === showGlobalStatus.value.event && temp.key === showGlobalStatus.value.key && temp.value === showGlobalStatus.value.value
            }
            return true
        }
        yunApi.zl_on_event('showComponent', window, (e) => {
            showGlobalStatus.value = {
                event: 'showComponent',
                key: e.detail.key,
                value: e.detail.value
            }
        })

        getLeftComponent()
        return {
            letfFormData,
            result,
            rightAttribute,
            moveEnd,
			moveStart,
            moveEvent,
            selectItem,
            change,
            curRowIndex,
            selectRow,
            flagString,
            changeDarg,
            endDrag,
            calculateFlag,
            setPropsValue,
            savePage,
            savePageDialog,
            pageInfo,
            getPageInfo,
            setAttr,
            showGlobalStatus,
            showComponent
        }
    },
    data() {
        return {
            // curIndex: -1,
            // letfFormData: [{
            //     name: '单行文本',
            //     type: 'textSingle'
            // }, {
            //     name: '多行文本',
            //     type: 'textArea'
            // }],
            result1: []
        }
    },
    methods: {
        strLen() {
            var str = '';
            for(var i = 0; i<16; i++) {
                str += (Math.floor((Math.random()*15)+1)).toString(16);
            }
            return str;
        },
        cloneItem(original) {
            let temp = JSON.parse(JSON.stringify(original))
            temp.uuid = this.strLen()
            return temp
        },
        // 移除组件
        removeItem(param) {
            param.list.splice(param.index, 1)
        },
        gotoPage() {
            this.$router.push('page-list')
        },
        // 预览页面
        gotoPrePage() {
            if (this.pageInfo.id) {
                this.$router.push({path: 'preview', query: {id: this.pageInfo.id}})
            } else {
                this.$message({
                    message: '请先保存再预览',
                    type: 'warning'
                })
            }
        }
    },
    created() {
        let query = this.$route.query
        if (query && query['id']) {
            this.getPageInfo(query.id)
        }
    },
    mounted() {
        
    }
}
</script>

<style scoped lang="less">
.form-part {
    .select-component {
        align-items: flex-start;
        flex-wrap: wrap;
    }
    .component-list {
        border-bottom: 1px solid #a0cfff;
    }
    .box-title {
        text-align: center;
    }
    .row-container {
        .page-tool {
            position: absolute;
            top: -15px;
            right: -14px;
            display: none;
            transition: all 0.5s ease;
        }
        &:hover {
            .page-tool {
                display: flex;
            }
        }
    }
    .middle {
		position: relative;
		padding: 15px;
		.show-component {
			width: calc(~"100% - 20px");
			min-height: calc(~"100% - 30px");
			padding: 0;
			position: absolute;
		}
        overflow: scroll;
	}
    .row-div {
        display: flex;
        justify-content: flex-start;
        flex-wrap: wrap;
        width: 100%;
        min-height: 50px;
        // border: 1px dashed rgba(60, 207, 255, 0.6);
    }
    .el-row {
        flex: 1 1 50%;
        margin: 10px 0;
    }
    .el-col {
        margin: 5px 0;
        &.left {
            display: flex;
            justify-content: flex-start;
            align-items: center;
            position: relative;
            border: 1px dashed rgba(60, 207, 255, 0.6);
            .page-tool {
                position: absolute;
                top: -15px;
                right: -14px;
                display: none;
                transition: all 0.5s ease;
            }
            &:hover {
                .page-tool {
                    display: flex;
                }
            }
        }
    }
    .drag-container {
        padding: 5px 10px;
        min-height: 80px;
        width: 100%;
        // border: 1px dashed rgba(60, 207, 255, 0.6);
    }
    .drag-padding {
        padding: 20px 0;
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        // border: 1px dashed rgba(60, 207, 255, 0.6);
    }
    .container {
        padding: 10px;
        position: relative;
        border: 1px solid rgba(160, 207, 255, 0.5);
        margin: 5px 0;
        &.active {
            border: 1px solid #a0cfff;
            box-shadow: 0px 0px 5px 3px rgba(160, 207, 255, .5);
        }
        &.fixed {
            position: absolute;
        }
    }
    .no-layout {
        // padding: 0 10px;
    }
    .row {
        display: flex;
    }
    .right {
        display: flex;
        flex-direction: column;
        .component-fr {
            flex: 1 1 auto;
            padding-top: 10px;
        }
    }
}
</style>
